﻿
#include <osg/Group>  
#include <osg/Geometry>  
#include <osg/PolygonMode>
#include <osg/ShapeDrawable>
#include <osgDB/ReadFile>  
#include <osgUtil/PrintVisitor>  
#include <osgViewer/ViewerEventHandlers>  
#include <osgViewer/Viewer>  
#include <iostream>  
#include <fstream>  
#include <sstream>  

#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>

#include <BRepMesh.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRep_Tool.hxx>
#include <gp_XYZ.hxx>
#include <BRepAlgo_Fuse.hxx>

#include <Poly_Connect.hxx>
#include <TColgp_Array1OfDir.hxx>
#include <StdPrs_ToolTriangulatedShape.hxx>
#include <BRepTools.hxx>

#include <BRepAlgoAPI_Cut.hxx>

#include <CSLib_DerivativeStatus.hxx>
#include <CSLib_NormalStatus.hxx>

#include <CSLib.hxx>

#include <OsgExTool/OsgExTool>
#include <DebugTool/DebugFunction>

#include <osg/ComputeBoundsVisitor>

#include <osg/TriangleFunctor>
#include <BaseTool/BaseTool>

#include <osgDB/FileUtils>

#include <OsgExTool/MergeGeometry>
#include <OsgExTool/BigTextureText>

#include <osg/LightModel>

//
#include <osgUtil/ReflectionMapGenerator>
#include <osgUtil/HighlightMapGenerator>
#include <osgUtil/HalfWayMapGenerator>

#include <osgUtil/DelaunayTriangulator>

#include <osg/TexEnvCombine>

#include <osgText/Text3D>

#include "OsgExTool/Tex2DDrawable.h"
#include "OsgExTool/MaterialManger.h"
#include <BRepPrimAPI_MakeBox.hxx>
#include <Standard_Real.hxx>



#include <OsgExTool/MergeGeometry>

using namespace OsgExTool;

#include <OsgExTool/CustumGeometry>

 osg::BoundingBox OsgExTool::OsgExToolSet::GetBSForFiles( std::vector<std::string>& pathList)
 {
	 osg::BoundingBox box;

	 box.init();

	 if (osgDB::fileExists("D://projection//box.txt"))
	 {
		 std::ifstream ifs("D://projection//box.txt");

		 float xmin, ymin, zmin, xmax, ymax, zmax;

         ifs>>xmin>>ymin>>zmin>>xmax>>ymax>>zmax;

		 ifs.close();

		 box.set(xmin, ymin, zmin, xmax, ymax, zmax);

		 return box;
	 }

	 std::vector<std::string>::iterator it = pathList.begin();

	 for(int i = 0; it != pathList.end(); it++, i++)
	 {
		 osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(*it);

		 if (node)
		 {
		     node->IsCalBound(true);
		     node->dirtyBound()    ;
		    
		     osg::ComputeBoundsVisitor boundVisitor;
		    
		     node->accept(boundVisitor);
		    
		     box.expandBy( boundVisitor.getBoundingBox() );
		    
             DebugTool::DebugFunction::OutputDebugInfo(pathList.size());
		    
		     DebugTool::DebugFunction::OutputDebugInfo(i);
		 }
	 }


	 if (!osgDB::fileExists("D://projection//box.txt"))
	 {
		 std::ofstream out("D://projection//box.txt");

		 out<<box.xMin()<<" "<<box.yMin()<<" "<<box.zMin()<<std::endl; 

		 out<<box.xMax()<<" "<<box.yMax()<<" "<<box.zMax()<<std::endl; 

		 out.close();
	 }


	 return box;
 }

 osg::BoundingBox OsgExTool::OsgExToolSet::GetBSForDirectory( std::string path )
 {
	 std::vector<std::string> pathList;

	 BaseTool::BaseToolSet::visit(path, 0, pathList);

	 return GetBSForFiles(pathList);
 }

 osg::BoundingBox OsgExTool::OsgExToolSet::GetBSForNode(osg::ref_ptr<osg::Node> node)
 {
	 if (node)
	 {
		 node->IsCalBound(true);
		 node->dirtyBound()    ;

		 osg::ComputeBoundsVisitor boundVisitor;
		 node->accept(boundVisitor);
		
		 return boundVisitor.getBoundingBox();
	 }

	 return osg::BoundingBox();
 }

 void OsgExTool::OsgExToolSet::WriteLodFile()
 {
	 //读数据

	 float lod[10] = {1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1};

	 size_t num = 10;

	 //生成文件夹
	 std::string Direcotory("D://lod//");

	 for (size_t i = 0; i < num; i++)
	 {
	 	std::stringstream ss;

	 	ss<<i;

	 	std::string str;

	 	ss>>str;

	 	str = Direcotory + str;

	 	osgDB::makeDirectory(str);
	 }
 }


void OsgExTool::OsgExToolSet::CreateLod()   
{
	//生成lod
	std::string Direcotoryd("D://lod//lod");

	std::string Direcotory("D://lod//");

	osgDB::makeDirectory(Direcotoryd);

	for (size_t k = 0; k < 10; k ++)
	{
		std::stringstream ss;

		ss<<k;

		std::string str;

		ss>>str;

		std::string d =  Direcotory + str;

		std::string out_d = Direcotoryd + std::string("//") + str + std::string(".ive");

		OsgExTool::MergeGeometryVisitor::GetMergeGeometry(DebugFunction::GetGroupForDirectory(d), out_d);
	}
}


void OsgExToolSet::TransformGeometry(osg::Geometry& geometry)
{
	//改写成三角形
	osg::Vec3Array* vertice = (osg::Vec3Array*)(geometry.getVertexArray() );
	osg::Vec3Array* normal = (osg::Vec3Array*)(geometry.getNormalArray() ) ;

	osg::Vec2Array* texcoord = (osg::Vec2Array*)(geometry.getTexCoordArray(0));


	typedef struct strNVC
	{
		osg::Vec3 v;
		osg::Vec3 n;
		osg::Vec2 t;

	} NVC;

	std::vector<NVC> nvc_vec;

	osg::DrawElementsUInt* drawArrays = dynamic_cast<osg::DrawElementsUInt*> (geometry.getPrimitiveSet(0));

	for (size_t i = 0; i < drawArrays->size(); i++)
	{
		NVC nvc;

		nvc.v = vertice->at(drawArrays->at(i));

		nvc.n = normal->at(drawArrays->at(i));

		if (texcoord)
		{
		    nvc.t = texcoord->at(drawArrays->at(i));
		}

		nvc_vec.push_back(nvc);
	}

	vertice->clear();
	normal->clear() ;

	if (texcoord)
	{
		texcoord->clear()  ;
	}
	

	for (size_t i = 0; i < nvc_vec.size(); i++)
	{
		vertice->push_back(nvc_vec[i].v);

		normal->push_back(nvc_vec[i].n) ;

		if (texcoord)
		{
			texcoord->push_back(nvc_vec[i].t)  ;
		}
	}

	geometry.setPrimitiveSet(0,  new osg::DrawArrays(GL_TRIANGLES, 0, vertice->size()) );
}



//void Bim_Interactiv::AddMarks(const osgGA::GUIEventAdapter& event)
//{
//	osg::Vec3 currentpoint = GetPickPoint(event,root_group_);
//
//	std::wstring markstr = L"阿卡迪亚小区";
//	AddMark(currentpoint,markstr,markstr);
//}

//二维显示 ，没有测试过
osg::ref_ptr<osg::Geode> OsgExToolSet::AddMark(osg::Vec3 pos,std::wstring strname,std::wstring textstr)
{
	osg::ref_ptr<osg::Geode> geode_ = new osg::Geode;
	std::string fontdir = "\\font\\迷你简竹节.ttf";

	osg::ref_ptr<osgText::Text> texttest = new osgText::Text;
	texttest->setFont(osgText::readFontFile(fontdir));
	texttest->setText(textstr.c_str());
	texttest->setCharacterSize(32.0f);
	texttest->setAutoRotateToScreen(true);
	texttest->setColor(osg::Vec4(1.0,1.0,1.0,1.0));
	texttest->setPosition(pos);
 	texttest->setAlignment(osgText::Text::RIGHT_BOTTOM);
 	texttest->setAxisAlignment(osgText::Text::SCREEN);
	texttest->setCharacterSizeMode(osgText::Text::SCREEN_COORDS);

	geode_->addDrawable(texttest);

	geode_->getOrCreateStateSet()->setMode(GL_BLEND,osg::StateAttribute::ON);
	geode_->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
	geode_->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
	geode_->getOrCreateStateSet()->setRenderBinDetails(1, "RenderBin");

	geode_->setName(osg::StringTools::WString2String(strname));
	
	return geode_;
};

osg::ref_ptr<osg::Geode> OsgExToolSet::CreateAxisLine(double len)
{
	double length = len * 0.5;
	osg::Vec3d x1(-length, 0, 0), x2(length, 0, 0);
	osg::Vec3d y1(0, -length, 0), y2(0, length, 0);

	osg::Vec3d z1(0, 0, -length), z2(0, 0, length);

	osg::ref_ptr<osg::Geode> geode = new osg::Geode();
	{
		osg::ref_ptr<osg::Vec3Array> vecarry1 = new osg::Vec3Array();

		osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();

		vecarry1->push_back(x1);
		vecarry1->push_back(x2);

		osg::ref_ptr<osg::Vec4Array> colorvec = new osg::Vec4Array();
		colorvec->push_back(osg::Vec4(1.0, 0.0, 0.0, 1.0));
		geometry->setColorArray(colorvec);
		geometry->setColorBinding(osg::Geometry::BIND_OVERALL);

		geometry->setVertexArray(vecarry1.get());
		geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, vecarry1->size()));


		geode->addDrawable(geometry.get());
	}


	{
		osg::ref_ptr<osg::Vec3Array> vecarry1 = new osg::Vec3Array();

		osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();

		vecarry1->push_back(y1);
		vecarry1->push_back(y2);

		osg::ref_ptr<osg::Vec4Array> colorvec = new osg::Vec4Array();
		colorvec->push_back(osg::Vec4(0.0, 1.0, 0.0, 0.0));
		geometry->setColorArray(colorvec);
		geometry->setColorBinding(osg::Geometry::BIND_OVERALL);

		geometry->setVertexArray(vecarry1.get());
		geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, vecarry1->size()));


		geode->addDrawable(geometry.get());
	}

	{
		osg::ref_ptr<osg::Vec3Array> vecarry1 = new osg::Vec3Array();

		osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();

		vecarry1->push_back(z1);
		vecarry1->push_back(z2);

		osg::ref_ptr<osg::Vec4Array> colorvec = new osg::Vec4Array();
		colorvec->push_back(osg::Vec4(0.0, 0.0, 1.0, 0.0));
		geometry->setColorArray(colorvec);
		geometry->setColorBinding(osg::Geometry::BIND_OVERALL);

		geometry->setVertexArray(vecarry1.get());
		geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, vecarry1->size()));


		//geode->addDrawable(geometry.get());
	}

	return geode;
}


osg::ref_ptr<osg::Geode> OsgExToolSet::CreateAxisLine(osg::Vec3f origin, osg::Vec3f dx, osg::Vec3f dy, osg::Vec3f dz, double length)
{
	dx.normalize();
	dy.normalize();
	dz.normalize();
	osg::Vec3f xLength = origin + dx * length;
	osg::Vec3f yLength = origin + dy * length;
	osg::Vec3f zLength = origin + dz * length;
	
	osg::ref_ptr<osg::Geode> geode = new osg::Geode();
	{
		osg::ref_ptr<osg::Vec3Array> vecarry1 = new osg::Vec3Array();

		osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();

		vecarry1->push_back(origin);
		vecarry1->push_back(xLength);

		osg::ref_ptr<osg::Vec4Array> colorvec = new osg::Vec4Array();
		colorvec->push_back(osg::Vec4(1.0, 0.0, 0.0, 1.0));
		geometry->setColorArray(colorvec);
		geometry->setColorBinding(osg::Geometry::BIND_OVERALL);

		geometry->setVertexArray(vecarry1.get());
		geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, vecarry1->size()));


		geode->addDrawable(geometry.get());
	}


	{
		osg::ref_ptr<osg::Vec3Array> vecarry1 = new osg::Vec3Array();

		osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();

		vecarry1->push_back(origin);
		vecarry1->push_back(yLength);

		osg::ref_ptr<osg::Vec4Array> colorvec = new osg::Vec4Array();
		colorvec->push_back(osg::Vec4(0, 1.0, 0.0, 0.0));
		geometry->setColorArray(colorvec);
		geometry->setColorBinding(osg::Geometry::BIND_OVERALL);

		geometry->setVertexArray(vecarry1.get());
		geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, vecarry1->size()));


		geode->addDrawable(geometry.get());
	}


	{
		osg::ref_ptr<osg::Vec3Array> vecarry1 = new osg::Vec3Array();

		osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();

		vecarry1->push_back(origin);
		vecarry1->push_back(zLength);

		osg::ref_ptr<osg::Vec4Array> colorvec = new osg::Vec4Array();
		colorvec->push_back(osg::Vec4(0.0, 0.0, 1.0, 0.0));
		geometry->setColorArray(colorvec);
		geometry->setColorBinding(osg::Geometry::BIND_OVERALL);

		geometry->setVertexArray(vecarry1.get());
		geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, vecarry1->size()));


		geode->addDrawable(geometry.get());
	}

	return geode;
}

osg::ref_ptr<osg::Geode> OsgExToolSet::CreateAxis(double clinder_height, double clinder_radius, double cone_height, double cone_radius)
{
	osg::ref_ptr<osg::Geode> axis = new osg::Geode();

	axis->setNodeMask(3);

	osg::TessellationHints *hins = new osg::TessellationHints;
	hins->setDetailRatio(1.0f); //设置圆柱的精度为0.1，值越小，精度越小
	
	{//z
	   osg::ref_ptr<osg::Cylinder> cyx = new osg::Cylinder;
	   osg::ref_ptr<osg::ShapeDrawable> sdx = new osg::ShapeDrawable(cyx);
	   cyx->setCenter(osg::Vec3(0,0,0));
	   cyx->setHeight(clinder_height);
	   cyx->setRadius(clinder_radius);
	   sdx->setColor(osg::Vec4(0, 0.0, 1.0, 1.0));
	   sdx->setTessellationHints(hins);

	   sdx->setName("hudcamera");
	   axis->addDrawable(sdx);
	}

	{//zcone
		osg::ref_ptr<osg::Cone> cyx = new osg::Cone;
		osg::ref_ptr<osg::ShapeDrawable> sdx = new osg::ShapeDrawable(cyx);
		cyx->setCenter(osg::Vec3(0,0,clinder_height * 0.5));
		cyx->setHeight(cone_height);
		cyx->setRadius(cone_radius);
		sdx->setColor(osg::Vec4(0.0, 0.0, 1.0, 1.0));
		sdx->setTessellationHints(hins);

		sdx->setName("hudcamera");

		axis->addDrawable(sdx);
	}

	{//x
		osg::ref_ptr<osg::Cylinder> cyy = new osg::Cylinder;  
		osg::ref_ptr<osg::ShapeDrawable> sdy = new osg::ShapeDrawable(cyy);
		cyy->setCenter(osg::Vec3(0,0,0));
		cyy->setHeight(clinder_height);
		cyy->setRadius(clinder_radius);

		osg::Quat quat;
		quat.makeRotate(osg::PI_2, osg::Vec3(0, 1, 0));
		cyy->setRotation(quat);
		sdy->setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0));
		sdy->setTessellationHints(hins);

		sdy->setName("hudcamera");
		axis->addDrawable(sdy);
	}

	{//xcone
		osg::ref_ptr<osg::Cone> cyy = new osg::Cone;  
	    osg::ref_ptr<osg::ShapeDrawable> sdy = new osg::ShapeDrawable(cyy);
		cyy->setCenter(osg::Vec3(clinder_height * 0.5, 0, 0));
	    cyy->setHeight(cone_height);
	    cyy->setRadius(cone_radius);
	    

	    osg::Quat quat;
	    quat.makeRotate(osg::PI_2, osg::Vec3(0, 1, 0));
	    cyy->setRotation(quat);
	    sdy->setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0));
	    sdy->setTessellationHints(hins);
		sdy->setName("hudcamera");
		axis->addDrawable(sdy);
	}

	{//y
		osg::ref_ptr<osg::Cylinder> cyz = new osg::Cylinder;  
		osg::ref_ptr<osg::ShapeDrawable> sdz = new osg::ShapeDrawable(cyz);
		cyz->setCenter(osg::Vec3(0,0,0));
		cyz->setHeight(clinder_height);
		cyz->setRadius(clinder_radius);

		osg::Quat quat;
		quat.makeRotate(osg::PI_2, osg::Vec3(1, 0, 0));
		cyz->setRotation(quat);
		sdz->setColor(osg::Vec4(0.0, 1.0, 0.0, 1.0));
		sdz->setTessellationHints(hins);

		axis->addDrawable(sdz);
	}

	{//y cone
		osg::ref_ptr<osg::Cone> cyz = new osg::Cone;  
		osg::ref_ptr<osg::ShapeDrawable> sdz = new osg::ShapeDrawable(cyz);
		cyz->setCenter(osg::Vec3(0, clinder_height * 0.5,0));
		cyz->setHeight(cone_height);
		cyz->setRadius(cone_radius);
		
		osg::Quat quat;
		quat.makeRotate(-osg::PI_2, osg::Vec3(1, 0, 0));
		cyz->setRotation(quat);
		sdz->setColor(osg::Vec4(0.0, 1.0, 0.0, 1.0));
		sdz->setTessellationHints(hins);

		axis->addDrawable(sdz);
	}


	return axis;
}

//
osg::ref_ptr<osg::MatrixTransform> OsgExTool::OsgExToolSet::createAxisPlane(osg::Matrixd& mat)
{
	double width = 6000;

	double color = 1.0;
	double alpha = 0.2;

	osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;

	{
		osg::ref_ptr<osg::MatrixTransform> mat = new osg::MatrixTransform();

		osg::Vec3d v1(width + width, width + width, 0);
		osg::Vec3d v2(width + width, -width + width, 0);
		osg::Vec3d v3(-width + width, -width + width, 0);
		osg::Vec3d v4(-width + width, width + width, 0);

		osg::ref_ptr<osg::Geometry> geom = CreateQuad(v1, v2, v3, v4, osg::Vec3f(0, 0, 2), osg::Vec4(color, 0.0, 0.0, alpha));
		geom->setStateSet(MaterialManager::getInstance()->getMaterialForId("texture_qianbai"));

		mat->addChild(geom);
		mt->addChild(mat);
	}

	double scale = (width + width) * 0.9;

	double scalex = (width + width) * 1.5;

	{
		osg::ref_ptr<osg::MatrixTransform> mat = new osg::MatrixTransform();

		osg::Vec3d v1(width + width, -width * 0.1, width);
		osg::Vec3d v2(width + width, 0, -width + width);
		osg::Vec3d v3(-width + width, 0, -width + width);
		osg::Vec3d v4(-scale* 0.1, -scale * 0.1, width);

		osg::ref_ptr<osg::Geometry> geom = CreateQuad(v1, v2, v3, v4, osg::Vec3f(0, 0, 1), osg::Vec4(0.0, color, 0.0, alpha));
		geom->setStateSet(MaterialManager::getInstance()->getMaterialForId("texture_diban"));

		mat->addChild(geom);

		//mat->setMatrix(osg::Matrixd::scale(1, 1, 10) * osg::Matrixd::rotate(0.1, osg::Vec3f(1, 0, 0)));

		mt->addChild(mat);
	}

	{
		osg::ref_ptr<osg::MatrixTransform> mat = new osg::MatrixTransform();

		osg::Vec3d v1(-width * 0.1, width + width, width);
		osg::Vec3d v2(0, width + width, -width + width);
		osg::Vec3d v3(0, -width + width, -width + width);
		osg::Vec3d v4(-scale * 0.1, -scale * 0.1, width);

		osg::Vec3d vector12(v2 - v1);
		osg::Vec3d vector13(v4 - v1);
		osg::Vec3d n = vector12^vector13;

		osg::ref_ptr<osg::Geometry> geom = CreateQuad(v1, v2, v3, v4, n, osg::Vec4(0.0, 0.0, color, alpha));
		geom->setStateSet(MaterialManager::getInstance()->getMaterialForId("texture_zhuanqiang"));
		mat->addChild(geom);

		//mat->setMatrix(osg::Matrixd::scale(1, 1, 10) * osg::Matrixd::rotate(-0.1, osg::Vec3f(0, 1, 0)));
		mt->addChild(mat);
	}

	mt->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
	mt->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);

	return mt;
}


osg::ref_ptr<osg::Geode> OsgExToolSet::CreateDelaunayTriangulator(std::vector<osg::Vec3f>& points)
{
	osg::ref_ptr<osg::Vec3Array> coords = new osg::Vec3Array();
	osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array();

	// 添加顶点数据  
	for (size_t i = 0; i < points.size();  i++)
	{
		coords->push_back(osg::Vec3(points[i][0], points[i][1], points[i][2]));
	}

	// 创建Delaunay三角网对象  
	osg::ref_ptr<osgUtil::DelaunayTriangulator> dt = new osgUtil::DelaunayTriangulator();

	dt->setInputPointArray(coords);//赋给它三维点集数组

	dt->setOutputNormalArray(normals);//输出法向量
	//生成三角网
	dt->triangulate();


	osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();
	//设置法线
	geometry->setNormalArray(normals.get());
	geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);

	osg::ref_ptr<osg::Vec4Array> colorvec = new osg::Vec4Array();
	colorvec->push_back(osg::Vec4(0, 0.8, 0.3, 1.0));
	geometry->setColorArray(colorvec);
	geometry->setColorBinding(osg::Geometry::BIND_OVERALL);


	// 创建几何体  
	
	geometry->setVertexArray(coords.get());  // 设置顶点数组  
	geometry->addPrimitiveSet(dt->getTriangles());// 加入到绘图基元  

	// 添加到叶节点  
	osg::ref_ptr<osg::Geode> geode = new osg::Geode();
	geode->addDrawable(geometry.get());

	return geode;

}

osg::ref_ptr<osg::Geode> OsgExToolSet::CreateLine(osg::Vec3d f, osg::Vec3d s, osg::Vec4 color)
{
     osg::Geode *geode = new osg::Geode();

	 osg::ref_ptr<osg::Vec3Array> vecarry1 = new osg::Vec3Array();

	 osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();

	 osg::ref_ptr<osg::Vec4Array> colorvec = new osg::Vec4Array();
	 colorvec->push_back(color);
	 geometry->setColorArray(colorvec);
	 geometry->setColorBinding(osg::Geometry::BIND_OVERALL);

	 {
		vecarry1->push_back(f);
	    vecarry1->push_back(s);

		geometry->setVertexArray(vecarry1.get());
		geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, vecarry1->size()));
	 }

	 geode->addDrawable(geometry.get());

	 return geode;
}


osg::Group* OsgExToolSet::createSunLight(osg::Node* node)
{
	osg::LightSource* sunLightSource = new osg::LightSource;

	osg::Light* sunLight = sunLightSource->getLight();

	sunLight->setLightNum(0);
	sunLight->setAmbient(osg::Vec4(0.6f,0.6f,0.6f,1.0f)) ;
	sunLight->setDiffuse(osg::Vec4(0.6f,0.6f,0.6f,1.0f)) ;
	sunLight->setSpecular(osg::Vec4(0.6f,0.6f,0.6f,1.0f));

	//影响包围盒的位置,直接放中心，以后改进
	osg::Vec3f center = node->getBound().center();
	osg::Vec3f pos = center; 
	sunLight->setPosition(osg::Vec4f(pos.x(), pos.y(), pos.z(), 1));

   // sunLight->setDirection(osg::Vec3(1, 1, 1));
	
	sunLightSource->setLight( sunLight );
	sunLightSource->setLocalStateSetModes( osg::StateAttribute::ON );
	sunLightSource->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON);

	osg::LightModel* lightModel = new osg::LightModel;

	lightModel->setAmbientIntensity(osg::Vec4(0.6f,0.6f,0.6f,1.0f));

	sunLightSource->getOrCreateStateSet()->setAttribute(lightModel);

	sunLightSource->addChild(node);

	return sunLightSource;
}


void OsgExToolSet::create_specular_highlights(osg::Node *node)
{
	osg::StateSet *ss = node->getOrCreateStateSet();

	// create and setup the texture object
	osg::TextureCubeMap *tcm = new osg::TextureCubeMap;
	tcm->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP);
	tcm->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP);
	tcm->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP);
	tcm->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
	tcm->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);    

	// generate the six highlight map images (light direction = [1, 1, -1])
	osgUtil::HighlightMapGenerator *mapgen = new osgUtil::HighlightMapGenerator(
		osg::Vec3(1, 1, -1),            // light direction
		osg::Vec4(1, 0.9f, 0.8f, 1),    // light color
		8);                             // specular exponent

	mapgen->generateMap();

	// assign the six images to the texture object
	tcm->setImage(osg::TextureCubeMap::POSITIVE_X, mapgen->getImage(osg::TextureCubeMap::POSITIVE_X));
	tcm->setImage(osg::TextureCubeMap::NEGATIVE_X, mapgen->getImage(osg::TextureCubeMap::NEGATIVE_X));
	tcm->setImage(osg::TextureCubeMap::POSITIVE_Y, mapgen->getImage(osg::TextureCubeMap::POSITIVE_Y));
	tcm->setImage(osg::TextureCubeMap::NEGATIVE_Y, mapgen->getImage(osg::TextureCubeMap::NEGATIVE_Y));
	tcm->setImage(osg::TextureCubeMap::POSITIVE_Z, mapgen->getImage(osg::TextureCubeMap::POSITIVE_Z));
	tcm->setImage(osg::TextureCubeMap::NEGATIVE_Z, mapgen->getImage(osg::TextureCubeMap::NEGATIVE_Z));

	// enable texturing, replacing any textures in the subgraphs
	ss->setTextureAttributeAndModes(0, tcm, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

	// texture coordinate generation
	osg::TexGen *tg = new osg::TexGen;
	tg->setMode(osg::TexGen::REFLECTION_MAP);
	ss->setTextureAttributeAndModes(0, tg, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

	// use TexEnvCombine to add the highlights to the original lighting
	osg::TexEnvCombine *te = new osg::TexEnvCombine;    
	te->setCombine_RGB(osg::TexEnvCombine::ADD);
	te->setSource0_RGB(osg::TexEnvCombine::TEXTURE);
	te->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
	te->setSource1_RGB(osg::TexEnvCombine::PRIMARY_COLOR);
	te->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);
	ss->setTextureAttributeAndModes(0, te, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
}


osg::ref_ptr<osg::Image> getNormalImage()
{
	osg::Vec3 origin(0.0f, 0.0f, 0.0f);

	unsigned int numColumns = 40;
	unsigned int numRows = 40   ;

	unsigned int r;
	unsigned int c;

	osg::HeightField* grid = new osg::HeightField;
	grid->allocate(numColumns, numRows);
	grid->setOrigin(origin); 

	grid->setXInterval(1.0);
	grid->setYInterval(1.0);

	for(r = 0; r < numRows; ++r)
	{
		for(c = 0; c < numColumns;++c)
		{
			grid->setHeight(c, r, rand() % 100);
		}
	}
	
	unsigned char* data = new unsigned char[24 * numRows * numColumns];

	for(r = 0; r < numRows; ++r)
	{
		for(c = 0; c < numColumns;++c)
		{
			osg::Vec3f n = grid->getNormal(c, r);

			data[3 * (r * numColumns + c)] = (n[0] + 1) * 0.5;
			data[3 * (r * numColumns + c)] = (n[1] + 1) * 0.5;
			data[3 * (r * numColumns + c)] = (n[2] + 1) * 0.5;
		}
	}

	//

	osg::ref_ptr<osg::Image> image_ = new osg::Image();
	image_->setImage(numColumns, numRows, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, data, osg::Image::USE_NEW_DELETE, 1);

	delete  [] data;

	return image_;
}

osg::ref_ptr<osg::Geode> OsgExToolSet::createHeightField()
{
	osg::Vec3 origin(0.0f, 0.0f, 0.0f);

	unsigned int numColumns = 40;
	unsigned int numRows = 40   ;

	unsigned int r;
	unsigned int c;

    osg::HeightField* grid = new osg::HeightField;
	grid->allocate(numColumns, numRows);
	grid->setOrigin(origin); 

	grid->setXInterval(1.0);
	grid->setYInterval(1.0);

	for(r = 0; r < numRows; ++r)
	{
		for(c = 0; c < numColumns;++c)
		{
			grid->setHeight(c, r, rand() % 5);
		}
	}

	osg::ref_ptr<osg::Geode> geode = new osg::Geode();
	geode->addDrawable(new osg::ShapeDrawable(grid)) ;

	return geode;
}



osg::ref_ptr<osg::Geode> OsgExToolSet::CreateQuadBox(osg::Vec3f center, double length, double width, double height, osg::Vec4 color)
{
	//长宽高，分辨是X,Y,Z轴
	length *= 0.5;
	width *= 0.5;
	height *= 0.5;

	osg::ref_ptr<osg::Geode> geode = new osg::Geode();
	//yoz
	//geode->addChild(CreateQuad(osg::Vec3d(length, width, height) + center, osg::Vec3d(length, -width, height) + center, osg::Vec3d(length, -width, -height) + center, osg::Vec3f(length, width, -height) + center, color));
	//geode->addChild(CreateQuad(osg::Vec3d(-length, width, height) + center, osg::Vec3d(-length, -width, height) + center, osg::Vec3d(-length, -width, -height) + center, osg::Vec3f(-length, width, -height) + center, color));

 //   //xoz
	//geode->addChild(CreateQuad(osg::Vec3d(length, width, height) + center, osg::Vec3d(-length, width, height) + center, osg::Vec3d(-length, width, -height) + center, osg::Vec3f(length, width, -height) + center, color));
	//geode->addChild(CreateQuad(osg::Vec3d(length, -width, height) + center, osg::Vec3d(-length, -width, height) + center, osg::Vec3d(-length, -width, -height) + center, osg::Vec3f(length, -width, -height) + center, color));

	////xoy
	//geode->addChild(CreateQuad(osg::Vec3d(length, width, height) + center, osg::Vec3d(-length, width, height) + center, osg::Vec3d(-length, -width, height) + center, osg::Vec3f(length, -width, height) + center, color));
	//geode->addChild(CreateQuad(osg::Vec3d(length, width, -height) + center, osg::Vec3d(-length, width, -height) + center, osg::Vec3d(-length, -width, -height) + center, osg::Vec3f(length, -width, -height) + center, color));
	
	osg::ref_ptr<CustumGeometry> geo1 = new CustumGeometry();
	osg::ref_ptr<CustumGeometry> geo2 = new CustumGeometry();
	osg::ref_ptr<CustumGeometry> geo3 = new CustumGeometry();
	osg::ref_ptr<CustumGeometry> geo4 = new CustumGeometry();
	osg::ref_ptr<CustumGeometry> geo5 = new CustumGeometry();
	osg::ref_ptr<CustumGeometry> geo6 = new CustumGeometry();


	geo1->setQuad(osg::Vec3d(length, width, height) + center, osg::Vec3d(length, -width, height) + center, osg::Vec3d(length, -width, -height) + center, osg::Vec3f(length, width, -height) + center);
	geo2->setQuad(osg::Vec3d(-length, width, height) + center, osg::Vec3d(-length, -width, height) + center, osg::Vec3d(-length, -width, -height) + center, osg::Vec3f(-length, width, -height) + center );

	//xoz
	geo3->setQuad(osg::Vec3d(length, width, height) + center, osg::Vec3d(-length, width, height) + center, osg::Vec3d(-length, width, -height) + center, osg::Vec3f(length, width, -height) + center);
	geo4->setQuad(osg::Vec3d(length, -width, height) + center, osg::Vec3d(-length, -width, height) + center, osg::Vec3d(-length, -width, -height) + center, osg::Vec3f(length, -width, -height) + center);

	//xoy
	geo5->setQuad(osg::Vec3d(length, width, height) + center, osg::Vec3d(-length, width, height) + center, osg::Vec3d(-length, -width, height) + center, osg::Vec3f(length, -width, height) + center);
	geo6->setQuad(osg::Vec3d(length, width, -height) + center, osg::Vec3d(-length, width, -height) + center, osg::Vec3d(-length, -width, -height) + center, osg::Vec3f(length, -width, -height) + center);
	
	geode->addChild(geo1);
	geode->addChild(geo2);

	geode->addChild(geo3);
	geode->addChild(geo4);

	geode->addChild(geo5);
	geode->addChild(geo6);
	
	return geode;
}


osg::ref_ptr<osg::Geode> OsgExToolSet::CreateQuadBoxTriangles_(osg::Vec3f center, double length, double width, double height, osg::Vec4 color)
{
	//长宽高，分辨是X,Y,Z轴
	length *= 0.5;
	width *= 0.5;
	height *= 0.5;

	osg::ref_ptr<osg::Geode> geode = new osg::Geode();

	osg::ref_ptr<osg::Geometry> geo1;

	if (length < 1)
	{
		geo1 = CreateQuad(osg::Vec3d(0, width, height) + center, osg::Vec3d(0, -width, height) + center, osg::Vec3d(0, -width, -height) + center, osg::Vec3f(0, width, -height) + center, osg::Vec3f(1, 0, 0), color);
	}else if (width < 1)
	{
		geo1 = CreateQuad(osg::Vec3d(length, 0, height) + center, osg::Vec3d(-length, 0, height) + center, osg::Vec3d(-length, 0, -height) + center, osg::Vec3f(length, 0, -height) + center, osg::Vec3f(0, 1, 0), color);
	}else if (height < 1)
	{
		geo1 = CreateQuad(osg::Vec3d(length, width, 0) + center, osg::Vec3d(-length, width, 0) + center, osg::Vec3d(-length, -width, 0) + center, osg::Vec3f(length, -width, 0) + center, osg::Vec3f(0, 0, 1), color);
	}


	geode->addChild(geo1);


	return geode;
}

//这个函数的法向量计算是错误的，需要改正。
void OsgExToolSet::createBoxGeometry(osg::Geode* geode, osg::BoundingBox& box, osg::Vec4f color)
{
	if (!geode)
	{
		geode = new osg::Geode();
	}

	osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;

	geom->setUseVertexBufferObjects(true);
	geom->setUseDisplayList(false);
	geom->setDataVariance(osg::Object::DYNAMIC);

	osg::ref_ptr<osg::Vec3Array> va = new osg::Vec3Array();
	osg::ref_ptr<osg::Vec3Array> normal = new osg::Vec3Array();
	osg::ref_ptr<osg::Vec4Array> colorvec = new osg::Vec4Array();

	colorvec->push_back(color);

	va->push_back(box.corner(0));
	va->push_back(box.corner(1));
	va->push_back(box.corner(2));
	va->push_back(box.corner(3));

	va->push_back(box.corner(4));
	va->push_back(box.corner(5));
	va->push_back(box.corner(6));
	va->push_back(box.corner(7));

	geom->setVertexArray(va.get());
	geom->setColorArray(colorvec);
	geom->setColorBinding(osg::Geometry::BIND_OVERALL);

	osg::ref_ptr<osg::DrawElementsUInt> quads = new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);

	quads->push_back(0);
	quads->push_back(1);
	quads->push_back(3);
	quads->push_back(2);

	quads->push_back(4);
	quads->push_back(5);
	quads->push_back(7);
	quads->push_back(6);

	quads->push_back(4);
	quads->push_back(6);
	quads->push_back(2);
	quads->push_back(0);

	quads->push_back(5);
	quads->push_back(7);
	quads->push_back(3);
	quads->push_back(1);

	quads->push_back(2);
	quads->push_back(3);
	quads->push_back(7);
	quads->push_back(6);

	quads->push_back(0);
	quads->push_back(1);
	quads->push_back(5);
	quads->push_back(4);

	geom->addPrimitiveSet(quads.get());

	geode->setName("bimXXX");
	geode->addChild(geom);
}

void OsgExToolSet::createBoxTriangles(osg::Geode* geode, osg::BoundingBox& box)
{
	osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;

	geom->setUseVertexBufferObjects(true);
	geom->setUseDisplayList(false);
	geom->setDataVariance(osg::Object::DYNAMIC);

	osg::ref_ptr<osg::Vec3Array> va = new osg::Vec3Array();
	//osg::ref_ptr<osg::Vec3Array> normal = new osg::Vec3Array();
	//osg::ref_ptr<osg::Vec4Array> colorvec = new osg::Vec4Array();

	//colorvec->push_back(color);

	va->push_back(box.corner(0));
	va->push_back(box.corner(1));
	va->push_back(box.corner(2));
	va->push_back(box.corner(3));

	va->push_back(box.corner(4));
	va->push_back(box.corner(5));
	va->push_back(box.corner(6));
	va->push_back(box.corner(7));

	geom->setVertexArray(va.get());
	//geom->setColorArray(colorvec);
	//geom->setColorBinding(osg::Geometry::BIND_OVERALL);

	osg::ref_ptr<osg::DrawElementsUInt> quads = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);

	quads->push_back(0);
	quads->push_back(1);
	quads->push_back(3);

	quads->push_back(0);
	quads->push_back(3);
	quads->push_back(2);

	quads->push_back(4);
	quads->push_back(5);
	quads->push_back(7);

	quads->push_back(4);
	quads->push_back(7);
	quads->push_back(6);

	quads->push_back(4);
	quads->push_back(6);
	quads->push_back(2);

	quads->push_back(4);
	quads->push_back(2);
	quads->push_back(0);

	quads->push_back(5);
	quads->push_back(7);
	quads->push_back(3);

	quads->push_back(5);
	quads->push_back(3);
	quads->push_back(1);

	quads->push_back(2);
	quads->push_back(3);
	quads->push_back(7);

	quads->push_back(2);
	quads->push_back(7);
	quads->push_back(6);

	quads->push_back(0);
	quads->push_back(1);
	quads->push_back(5);

	quads->push_back(0);
	quads->push_back(5);
	quads->push_back(4);

	geom->addPrimitiveSet(quads.get());
	geode->addChild(geom);
}

void OsgExToolSet::CreateBoxLine(osg::Geode* geode, osg::BoundingBox& box, osg::Vec4 color)
{
	//	box.scaleByLittle(1.0);
	osg::ref_ptr<osg::Geometry> geom7 = new osg::Geometry;

	geom7->setUseVertexBufferObjects(true);
	geom7->setUseDisplayList(false);
	geom7->setDataVariance(osg::Object::DYNAMIC);

	osg::ref_ptr<osg::Vec3Array> va = new osg::Vec3Array();
	osg::ref_ptr<osg::Vec4Array> colorvec = new osg::Vec4Array();

	colorvec->push_back(color);

	va->push_back(box.corner(0));
	va->push_back(box.corner(1));
	va->push_back(box.corner(2));

	va->push_back(box.corner(3));

	va->push_back(box.corner(4));
	va->push_back(box.corner(5));

	va->push_back(box.corner(6));
	va->push_back(box.corner(7));

	geom7->setVertexArray(va.get());
	geom7->setColorArray(colorvec);
	geom7->setColorBinding(osg::Geometry::BIND_OVERALL);

	osg::ref_ptr<osg::DrawElementsUInt> quads = new osg::DrawElementsUInt(osg::PrimitiveSet::LINES, 0);

	quads->push_back(0);
	quads->push_back(1);

	quads->push_back(0);
	quads->push_back(2);

	quads->push_back(2);
	quads->push_back(3);

	quads->push_back(3);
	quads->push_back(1);
	//
	quads->push_back(4);
	quads->push_back(5);

	quads->push_back(4);
	quads->push_back(6);

	quads->push_back(5);
	quads->push_back(7);

	quads->push_back(6);
	quads->push_back(7);
	//
	quads->push_back(0);
	quads->push_back(4);

	quads->push_back(1);
	quads->push_back(5);

	quads->push_back(2);
	quads->push_back(6);

	quads->push_back(3);
	quads->push_back(7);

	geom7->addPrimitiveSet(quads.get());
	geode->addChild(geom7);
}

void OsgExToolSet::CreateQuadBoxs(osg::Geode* geode, std::vector<osg::BoundingBox>& box, osg::Vec4 color)
{
	std::for_each(box.begin(), box.end(), [&](osg::BoundingBox& box){
		CreateQuadBoxTriangles(geode, box, color);
	});
}

void OsgExToolSet::CreateQuadBoxTriangles(osg::Geode* geode, osg::BoundingBox& box, osg::Vec4 color, bool isTextRoate)
{
	osg::Vec3f center;
	double length, width, height;

	box.getCLWHInfo(center, length, width, height);

	//长宽高，分辨是X,Y,Z轴
	length *= 0.5;
	width *= 0.5;
	height *= 0.5;

	if (!geode)
	{
		geode = new osg::Geode();
	}	
	box.getPlanesInfo();
	for (int i = 0; i < 6; ++i)
	{
		box.mPlane[i].getPoints();
	}
	osg::ref_ptr<osg::Geometry> geo1 = CreateQuad(box.mPlane[0].mPoints[0], box.mPlane[0].mPoints[1], box.mPlane[0].mPoints[2], box.mPlane[0].mPoints[3], osg::Vec3f(1, 0, 0), color, isTextRoate);
	if ("" != box.mTextID[0])
		geo1->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextID[0]));
	else if ("" != box.mTextIDTotal)
		geo1->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextIDTotal));

	osg::ref_ptr<osg::Geometry> geo2 = CreateQuad(box.mPlane[1].mPoints[0], box.mPlane[1].mPoints[1], box.mPlane[1].mPoints[2], box.mPlane[1].mPoints[3], osg::Vec3f(-1, 0, 0), color, isTextRoate);
	if ("" != box.mTextID[1])
		geo2->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextID[1]));
	else if ("" != box.mTextIDTotal)
		geo2->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextIDTotal));
	//xoz
	osg::ref_ptr<osg::Geometry> geo3 = CreateQuad(box.mPlane[2].mPoints[0], box.mPlane[2].mPoints[1], box.mPlane[2].mPoints[2], box.mPlane[2].mPoints[3], osg::Vec3f(0, 1, 0), color, isTextRoate);
	if ("" != box.mTextID[2])
		geo3->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextID[2]));
	else if ("" != box.mTextIDTotal)
		geo3->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextIDTotal));
	osg::ref_ptr<osg::Geometry> geo4 = CreateQuad(box.mPlane[3].mPoints[0], box.mPlane[3].mPoints[1], box.mPlane[3].mPoints[2], box.mPlane[3].mPoints[3], osg::Vec3f(0, -1, 0), color, isTextRoate);
	if ("" != box.mTextID[3])
		geo4->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextID[3]));
	else if ("" != box.mTextIDTotal)
		geo4->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextIDTotal));

	//xoy
	osg::ref_ptr<osg::Geometry> geo5 = CreateQuad(box.mPlane[4].mPoints[0], box.mPlane[4].mPoints[1], box.mPlane[4].mPoints[2], box.mPlane[4].mPoints[3], osg::Vec3f(0, 0, 1), color, isTextRoate);
	if ("" != box.mTextID[4])
		geo5->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextID[4]));
	else if ("" != box.mTextIDTotal)
		geo5->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextIDTotal));
	osg::ref_ptr<osg::Geometry> geo6 = CreateQuad(box.mPlane[5].mPoints[0], box.mPlane[5].mPoints[1], box.mPlane[5].mPoints[2], box.mPlane[5].mPoints[3], osg::Vec3f(0, 0, -1), color, isTextRoate);
	if ("" != box.mTextID[5])
		geo6->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextID[5]));
	else if ("" != box.mTextIDTotal)
		geo6->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextIDTotal));
	//box.mPlane[0].getPoints()
	//box.getPlanesInfo()
	//osg::ref_ptr<osg::Geometry> geo1 = CreateQuad(osg::Vec3d(length, width, height) + center, osg::Vec3d(length, -width, height) + center, osg::Vec3d(length, -width, -height) + center, osg::Vec3f(length, width, -height) + center, osg::Vec3f(1, 0, 0), color, isTextRoate);
	//if ("" != box.mTextID[0])
	//	geo1->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextID[0]));
	//else if ("" != box.mTextIDTotal)
	//	geo1->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextIDTotal));

	//osg::ref_ptr<osg::Geometry> geo2 = CreateQuad(osg::Vec3d(-length, width, height) + center, osg::Vec3d(-length, -width, height) + center, osg::Vec3d(-length, -width, -height) + center, osg::Vec3f(-length, width, -height) + center, osg::Vec3f(-1, 0, 0), color, isTextRoate);
	//if ("" != box.mTextID[1])
	//	geo2->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextID[1]));
	//else if ("" != box.mTextIDTotal)
	//	geo2->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextIDTotal));
	////xoz
	//osg::ref_ptr<osg::Geometry> geo3 = CreateQuad(osg::Vec3d(length, width, height) + center, osg::Vec3d(-length, width, height) + center, osg::Vec3d(-length, width, -height) + center, osg::Vec3f(length, width, -height) + center, osg::Vec3f(0, 1, 0), color, isTextRoate);
	//if ("" != box.mTextID[2])
	//	geo3->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextID[2]));
	//else if ("" != box.mTextIDTotal)
	//	geo3->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextIDTotal));
	//osg::ref_ptr<osg::Geometry> geo4 = CreateQuad(osg::Vec3d(length, -width, height) + center, osg::Vec3d(-length, -width, height) + center, osg::Vec3d(-length, -width, -height) + center, osg::Vec3f(length, -width, -height) + center, osg::Vec3f(0, -1, 0), color, isTextRoate);
	//if ("" != box.mTextID[3])
	//	geo4->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextID[3]));
	//else if ("" != box.mTextIDTotal)
	//	geo4->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextIDTotal));

	////xoy
	//osg::ref_ptr<osg::Geometry> geo5 = CreateQuad(osg::Vec3d(length, width, height) + center, osg::Vec3d(-length, width, height) + center, osg::Vec3d(-length, -width, height) + center, osg::Vec3f(length, -width, height) + center, osg::Vec3f(0, 0, 1), color, isTextRoate);
	//if ("" != box.mTextID[4])
	//	geo5->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextID[4]));
	//else if ("" != box.mTextIDTotal)
	//	geo5->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextIDTotal));
	//osg::ref_ptr<osg::Geometry> geo6 = CreateQuad(osg::Vec3d(length, width, -height) + center, osg::Vec3d(-length, width, -height) + center, osg::Vec3d(-length, -width, -height) + center, osg::Vec3f(length, -width, -height) + center, osg::Vec3f(0, 0, -1), color, isTextRoate);
	//if ("" != box.mTextID[5])
	//	geo6->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextID[5]));
	//else if ("" != box.mTextIDTotal)
	//	geo6->setStateSet(MaterialManager::getInstance()->getMaterialForId(box.mTextIDTotal));

	//osg::Texture2D* texture2d = (osg::Texture2D*)geode->getOrCreateStateSet()->getTextureAttribute(0, osg::StateAttribute::TEXTURE);
	//geo1->getOrCreateStateSet()->->setAttributeAndModes(attr, osg::StateAttribute::ON | osg::StateAttribute::PROTECTED);

	geo1->setName(box.mPlane[0].mName);
	geo2->setName(box.mPlane[1].mName);
	geo3->setName(box.mPlane[2].mName);
	geo4->setName(box.mPlane[3].mName);
	geo5->setName(box.mPlane[4].mName);
	geo6->setName(box.mPlane[5].mName);

	geode->addChild(geo1);
	geode->addChild(geo2);

	geode->addChild(geo3);
	geode->addChild(geo4);

	geode->addChild(geo5);
	geode->addChild(geo6);

}

osg::ref_ptr<osg::Geometry> OsgExToolSet::CreateQuad(osg::Vec3d v1, osg::Vec3d v2, osg::Vec3d v3, osg::Vec3f v4, osg::Vec3f normalv, osg::Vec4 color, bool isTextRotate)
{
	osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;

	geom->setName("bimBox");

	geom->setUseVertexBufferObjects(true);
	geom->setUseDisplayList(false);
	geom->setDataVariance(osg::Object::DYNAMIC);

	osg::ref_ptr<osg::Vec3Array> va = new osg::Vec3Array();
	osg::ref_ptr<osg::Vec3Array> normal = new osg::Vec3Array();
	osg::ref_ptr<osg::Vec4Array> colorvec = new osg::Vec4Array();

	colorvec->push_back(color);

	va->push_back(v1);
	va->push_back(v2);
	va->push_back(v3);
	va->push_back(v4);

	//加上纹理坐标 会影像颜色值
	osg::ref_ptr<osg::Vec2Array> tex = new osg::Vec2Array();

	tex->push_back(osg::Vec2(0, 0));
	tex->push_back(osg::Vec2(1, 0));
	tex->push_back(osg::Vec2(1, 1));
	tex->push_back(osg::Vec2(0, 1));

	geom->setTexCoordArray(0, tex, osg::Array::BIND_PER_VERTEX);

	//计算法向量
	//osg::Vec3d vector12(v2 - v1);
	//osg::Vec3d vector13(v4 - v1);
	//osg::Vec3d n = vector12^vector13;

	//n.normalize();

	normal->push_back(normalv);
	normal->push_back(normalv);
	normal->push_back(normalv);
	normal->push_back(normalv);

	//法向量会影响光照的颜色
	geom->setNormalArray(normal);
	geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);

	geom->setVertexArray(va.get());
	geom->setColorArray(colorvec);
	geom->setColorBinding(osg::Geometry::BIND_OVERALL);

	osg::ref_ptr<osg::DrawElementsUInt> quads = new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);

	quads->push_back(0);
	quads->push_back(1);
	quads->push_back(2);
	quads->push_back(3);

	geom->addPrimitiveSet(quads.get());

	return geom;
}

osg::ref_ptr<osg::Geode> OsgExToolSet::CreateQuadGeode(osg::Vec3d v1, osg::Vec3d v2, osg::Vec3d v3, osg::Vec3f v4, osg::Vec4 color)
{
	osg::ref_ptr<osg::Geode> geode = new osg::Geode();

	osg::Vec3d vector12(v2 - v1);
	osg::Vec3d vector13(v4 - v1);
	osg::Vec3d n = vector12^vector13;

	geode->addChild(CreateQuad(v1, v2, v3, v4, n, color));

	return geode;
}

osg::ref_ptr<osg::MatrixTransform> OsgExToolSet::createMatrixNode(osg::ref_ptr<osg::Node> node, osg::Vec3f start, osg::Vec3f end, osg::Vec3f pos)
{
	osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform();

	osg::Matrixf trs;
	trs.makeIdentity();

	trs.makeTranslate(pos);

	osg::Matrixf rot;
	rot.makeRotate(start, end);

	osg::Matrixf mat = rot * trs;

	mt->setMatrix(mat);
	mt->addChild(node);

	return mt;
}

osg::ref_ptr<osg::Geode> OsgExToolSet::createTexText(const osg::Vec3& pos, float radius)
{
	osg::ref_ptr<osg::Geode> geode = new osg::Geode;

	osg::ref_ptr<osgText::Text> text = new osgText::Text;

	text->setFont("D://xxx.ttf");
	text->setPosition(pos);
	text->setDrawMode(osgText::Text::TEXT | osgText::Text::BOUNDINGBOX);
	text->setAxisAlignment(osgText::Text::XY_PLANE);
	text->setText(L"阿卡迪亚小区");

	geode->addDrawable(text);

	osg::Material* front = new osg::Material;
	front->setAlpha(osg::Material::FRONT_AND_BACK, 1);
	front->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0.2, 0.2, 0.2, 1.0));
	front->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(.0, .0, 1.0, 1.0));
	geode->getOrCreateStateSet()->setAttributeAndModes(front);

	return geode;
}

//读入文字，直接放入大纹理
//生成多个四边形，一个四边形对应一个纹理
osg::ref_ptr<osg::Geode> OsgExToolSet::createBigTexText(const osg::Vec3& pos, float radius)
{
	osg::ref_ptr<osg::Geode> geode = new osg::Geode;

	osg::ref_ptr<osgText::BigTextureText> text = new osgText::BigTextureText;

	//加载字库
	text->setFont("D://xxx.ttf");

	//text->s


	text->setPosition(pos);
	text->setDrawMode(osgText::BigTextureText::TEXT | osgText::BigTextureText::BOUNDINGBOX);
	text->setAxisAlignment(osgText::BigTextureText::XY_PLANE);
	text->addText(L"阿卡迪亚小区");

	geode->addDrawable(text);

	osg::Material* front = new osg::Material;
	front->setAlpha(osg::Material::FRONT_AND_BACK, 1);
	front->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0.2, 0.2, 0.2, 1.0));
	front->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(.0, .0, 1.0, 1.0));
	geode->getOrCreateStateSet()->setAttributeAndModes(front);

	return text->createBigGeode();
}

osg::ref_ptr<osg::Geode> OsgExToolSet::create3DText(const osg::Vec3& pos, float radius)
{
	osg::ref_ptr<osg::Geode> geode = new osg::Geode;

	osg::ref_ptr<osgText::Text3D> text = new osgText::Text3D;

	text->setFont("D://xxx.ttf");
	//	text1->setCharacterSize(characterSize);
	//	text1->setCharacterDepth(characterDepth);
	text->setPosition(pos);
	text->setDrawMode(osgText::Text3D::TEXT | osgText::Text3D::BOUNDINGBOX);
	text->setAxisAlignment(osgText::Text3D::XY_PLANE);
	text->setText(L"阿卡迪亚小区");

	geode->addDrawable(text);

	//osg::ref_ptr<osgText::Style> style = new osgText::Style;
	//osg::ref_ptr<osgText::Bevel> bevel = new osgText::Bevel;
	//bevel->roundedBevel2(0.25);
	//style->setBevel(bevel.get());
	//style->setWidthRatio(0.4f);

	osg::Material* front = new osg::Material;
	front->setAlpha(osg::Material::FRONT_AND_BACK, 1);
	front->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0.2, 0.2, 0.2, 1.0));
	front->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(.0, .0, 1.0, 1.0));
	geode->getOrCreateStateSet()->setAttributeAndModes(front);

	return geode;
}


osg::ref_ptr<osg::Geode> OsgExToolSet::createBoxsGeode(std::vector<osg::Vec3f>& points, double width, double height, osg::Vec4 color)
{
	osg::ref_ptr<osg::Geode> geode = new osg::Geode;

	for (size_t j = 0; j < points.size() - 1; j++)
	{
		osg::Vec3 f = points[j];
		osg::Vec3 s = points[j + 1];
		osg::Vec3 n(s - f);

		n.normalize();
		osg::Vec3 T(-n.y(), 0, n.x());

		osg::Vec3 f2 = f + T * width * 0.5;
		f = f - T * width * 0.5;

		osg::Vec3 s2 = s + T * width * 0.5;
		s = s - T * width * 0.5;

		//
		osg::Matrixf rot;
		rot.makeIdentity();
		rot.makeRotate(osg::Vec3f(0, 0, 1), n);

		osg::Quat quat = rot.getRotate();

		double zWidth = (f - s).length();

		osg::Vec3f center = (f + s) * 0.5 + osg::Vec3f(0, height * 0.5, 0);

		osg::ref_ptr<osg::Box> box = new osg::Box(osg::Vec3f(center[0], -center[1], center[2]), width, 2.0, zWidth);
		osg::ref_ptr<osg::ShapeDrawable> sp = new osg::ShapeDrawable(box.get());
		sp->setColor(color);

		box->setRotation(quat);

		geode->addDrawable(sp.get());
	}

	geode->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
	geode->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);

	return geode;
}

//二维图形
osg::ref_ptr<osg::Projection> OsgExToolSet::createNormalText()
{
	osg::ref_ptr<osg::Geode> geode = new osg::Geode();
	osg::ref_ptr<osg::MatrixTransform> modeview = new osg::MatrixTransform();

	osg::ref_ptr<Tex2DDrawable> tex2d = new Tex2DDrawable();

	geode->addChild(tex2d);

	modeview->addChild(geode);

	modeview->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
	modeview->setMatrix(osg::Matrix::identity());
	modeview->addChild(geode);

	osg::ref_ptr<osg::Projection> projection = new osg::Projection;

	projection->setMatrix(osg::Matrix::ortho2D(0, 800, 0, 480));
	projection->addChild(modeview);

	return projection;
}


osg::ref_ptr<osg::Geode> OsgExToolSet::createPixelText()
{
	osg::ref_ptr<osg::Geode> pGeode = new osg::Geode();
	osg::ref_ptr<osgText::Text> pText = 0;


	pText = new osgText::Text();

	pText->setColor(osg::Vec4f(1.0, 1.0, 1.0, 1.0));
	pText->setPosition(osg::Vec3f(0, 0, 0));
	pText->setAxisAlignment(osgText::Text::XZ_PLANE);

	pText->setCharacterSize(20.0);

	pText->setCharacterSizeMode(osgText::Text::SCREEN_COORDS);
	pText->setFontResolution(32, 32);
	pText->setAlignment(osgText::Text::LEFT_CENTER);

	pText->setLayout(osgText::Text::LEFT_TO_RIGHT);
	pText->setBackdropType(osgText::Text::NONE);

	pText->setColorGradientMode(osgText::Text::SOLID);

	//QString version = "V1.16.0";
	//QString text = QString("OsgDemo %1(作者:红模仿 QQ21497936 博客地址: blog.csdn.net/qq21497936)").arg(version);
	//pText->setText(text.toStdString(), osgText::String::ENCODING_UTF8);

	pText->setText("xxxx");
	//pText->setFont(osgText::readFontFile("fonts/simsun.ttc"));
	pText->setAxisAlignment(osgText::Text::SCREEN);

	pGeode->addDrawable(pText.get());

	return pGeode;
}


osg::ref_ptr<osg::Geode> OsgExToolSet::FontGeode()
{
	osg::ref_ptr<osg::Geode> geode = new osg::Geode();

	return geode;
}

osg::ref_ptr<osg::Camera> OsgExToolSet::RTTCamera()
{
	osg::ref_ptr<osg::Camera> camera = new osg::Camera;

	camera->setViewport(0, 0, 256, 256);

	osg::Image* img = new osg::Image;
	img->allocateImage(256, 256, 1, GL_RGBA, GL_FLOAT);

	osg::Texture2D* texture2D = new osg::Texture2D;


	texture2D->setTextureSize(256, 256);
	texture2D->setInternalFormat(GL_RGBA);

	camera->attach(osg::Camera::COLOR_BUFFER, img, 0, 0);
	texture2D->setImage(0, img);

	//	camera->setProjectionMatrixAsFrustum(-proj_right,proj_right,-proj_top,proj_top,znear,zfar);
	//  
	camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
	//	camera->setViewMatrixAsLookAt(bs.center()-osg::Vec3(0.0f,2.0f,0.0f)*bs.radius(),bs.center(),osg::Vec3(0.0f,0.0f,1.0f));

	camera->setRenderOrder(osg::Camera::PRE_RENDER);
	camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);

	//camera->addChild(node);

	return camera;
}

void ComputeNormal(const TopoDS_Face& aFace,
	Poly_Connect& pc,
	TColgp_Array1OfDir& Nor)
{
	const Handle(Poly_Triangulation)& T = pc.Triangulation();
	BRepAdaptor_Surface S;
	Standard_Boolean hasUV = T->HasUVNodes();
	Standard_Integer i;
	TopLoc_Location l;
	Handle(Geom_Surface) GS = BRep_Tool::Surface(aFace, l);

	if (hasUV && !GS.IsNull()) {
		Standard_Boolean OK = Standard_True;
		gp_Vec D1U, D1V;
		gp_Vec D2U, D2V, D2UV;
		gp_Pnt P;
		Standard_Real U, V;
		CSLib_DerivativeStatus Status;
		CSLib_NormalStatus NStat;
		S.Initialize(aFace);
		const TColgp_Array1OfPnt2d& UVNodes = T->UVNodes();
		for (i = UVNodes.Lower(); i <= UVNodes.Upper(); i++) {
			U = UVNodes(i).X();
			V = UVNodes(i).Y();
			S.D1(U, V, P, D1U, D1V);
			CSLib::Normal(D1U, D1V, Precision::Angular(), Status, Nor(i));
			if (Status != CSLib_Done) {
				S.D2(U, V, P, D1U, D1V, D2U, D2V, D2UV);
				CSLib::Normal(D1U, D1V, D2U, D2V, D2UV, Precision::Angular(), OK, NStat, Nor(i));
			}
			if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse();
		}
	}
	else {
		const TColgp_Array1OfPnt& Nodes = T->Nodes();
		Standard_Integer n[3];
		const Poly_Array1OfTriangle& triangles = T->Triangles();

		for (i = Nodes.Lower(); i <= Nodes.Upper(); i++) {
			gp_XYZ eqPlan(0, 0, 0);
			for (pc.Initialize(i); pc.More(); pc.Next()) {
				triangles(pc.Value()).Get(n[0], n[1], n[2]);
				gp_XYZ v1(Nodes(n[1]).Coord() - Nodes(n[0]).Coord());
				gp_XYZ v2(Nodes(n[2]).Coord() - Nodes(n[1]).Coord());
				eqPlan += (v1^v2).Normalized();
			}
			Nor(i) = gp_Dir(eqPlan);
			if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse();
		}
	}
}

/*
Parameters
theShape	the shape with precomputed triangulation
theHasTexels	define UV coordinates in primitive array
theUVOrigin	origin for UV coordinates
theUVRepeat	repeat parameters for UV coordinates
theUVScale	scale coefficients for UV coordinates
*/

//! Gets triangulation of every face of shape and fills output array of triangles
osg::ref_ptr<osg::Geode> fillTriangles(const TopoDS_Shape&    theShape,
	const Standard_Boolean theHasTexels,
	const gp_Pnt2d&        theUVOrigin,
	const gp_Pnt2d&        theUVRepeat,
	const gp_Pnt2d&        theUVScale)
{
	osg::ref_ptr<osg::Geode> geode = new osg::Geode();
	osg::ref_ptr<osg::Geometry> triGeom = new osg::Geometry();
	osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array();
	osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array();
	osg::ref_ptr<osg::Vec2Array> tex = new osg::Vec2Array();

	BRepMesh_IncrementalMesh iMesh(theShape, 1);

	Handle(Poly_Triangulation) aT;
	TopLoc_Location aLoc;
	gp_Pnt aPoint;
	Standard_Integer aNbTriangles = 0;
	Standard_Integer aNbVertices = 0;

	// Precision for compare square distances
	const Standard_Real aPreci = Precision::SquareConfusion();

	TopExp_Explorer aFaceIt(theShape, TopAbs_FACE);
	for (; aFaceIt.More(); aFaceIt.Next())
	{
		const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
		aT = BRep_Tool::Triangulation(aFace, aLoc);
		if (!aT.IsNull())
		{
			aNbTriangles += aT->NbTriangles();
			aNbVertices += aT->NbNodes();
		}
	}


	Standard_Real aUmin(0.0), aUmax(0.0), aVmin(0.0), aVmax(0.0), dUmax(0.0), dVmax(0.0);
	for (aFaceIt.Init(theShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
	{
		const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
		aT = BRep_Tool::Triangulation(aFace, aLoc);
		if (aT.IsNull())
		{
			continue;
		}
		const gp_Trsf& aTrsf = aLoc.Transformation();

		// Determinant of transform matrix less then 0 means that mirror transform applied.
		Standard_Boolean isMirrored = aTrsf.VectorialPart().Determinant() < 0;

		Poly_Connect aPolyConnect(aT);
		// Extracts vertices & normals from nodes
		const TColgp_Array1OfPnt&   aNodes = aT->Nodes();
		const TColgp_Array1OfPnt2d& aUVNodes = aT->UVNodes();
		TColgp_Array1OfDir aNormals(aNodes.Lower(), aNodes.Upper());
		ComputeNormal(aFace, aPolyConnect, aNormals);

		if (theHasTexels)
		{
			BRepTools::UVBounds(aFace, aUmin, aUmax, aVmin, aVmax);
			dUmax = (aUmax - aUmin);
			dVmax = (aVmax - aVmin);
		}


		for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
		{
			aPoint = aNodes(aNodeIter);
			if (!aLoc.IsIdentity())
			{
				aPoint.Transform(aTrsf);

				aNormals(aNodeIter) = aNormals(aNodeIter).Transformed(aTrsf);
			}

			if (theHasTexels && aUVNodes.Upper() == aNodes.Upper())
			{
				const gp_Pnt2d aTexel = gp_Pnt2d((-theUVOrigin.X() + (theUVRepeat.X() * (aUVNodes(aNodeIter).X() - aUmin)) / dUmax) / theUVScale.X(),
					(-theUVOrigin.Y() + (theUVRepeat.Y() * (aUVNodes(aNodeIter).Y() - aVmin)) / dVmax) / theUVScale.Y());
				//anArray->AddVertex(aPoint, aNormals(aNodeIter), aTexel);

				int xx = 0;
			}
		}

		// Fill array with vertex and edge visibility info
		const Poly_Array1OfTriangle& aTriangles = aT->Triangles();
		Standard_Integer anIndex[3];
		for (Standard_Integer aTriIter = 1; aTriIter <= aT->NbTriangles(); ++aTriIter)
		{
			if ((aFace.Orientation() == TopAbs_REVERSED) ^ isMirrored)
			{
				aTriangles(aTriIter).Get(anIndex[0], anIndex[2], anIndex[1]);
			}
			else
			{
				aTriangles(aTriIter).Get(anIndex[0], anIndex[1], anIndex[2]);
			}

			gp_Pnt aP1 = aNodes(anIndex[0]);
			gp_Pnt aP2 = aNodes(anIndex[1]);
			gp_Pnt aP3 = aNodes(anIndex[2]);

			gp_Vec aV1(aP1, aP2);
			if (aV1.SquareMagnitude() <= aPreci)
			{
				continue;
			}
			gp_Vec aV2(aP2, aP3);
			if (aV2.SquareMagnitude() <= aPreci)
			{
				continue;
			}
			gp_Vec aV3(aP3, aP1);
			if (aV3.SquareMagnitude() <= aPreci)
			{
				continue;
			}
			aV1.Normalize();
			aV2.Normalize();
			aV1.Cross(aV2);
			if (aV1.SquareMagnitude() > aPreci)
			{
				//anArray->AddEdge(anIndex[0] + aDecal);
				//anArray->AddEdge(anIndex[1] + aDecal);
				//anArray->AddEdge(anIndex[2] + aDecal);

			}
		}
	}

	return geode;

}



osg::ref_ptr<osg::Geode> BuildShapeMesh(const TopoDS_Shape& aShape)

{
	BRepMesh_IncrementalMesh iMesh(aShape, 1);

	osg::ref_ptr<osg::Geode> geode = new osg::Geode();
	osg::ref_ptr<osg::Geometry> triGeom = new osg::Geometry();
	osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array();
	osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array();
	osg::ref_ptr<osg::Vec2Array> texs = new osg::Vec2Array();

	TopExp_Explorer faceExplorer;
	Standard_Real aUmin(0.0), aUmax(0.0), aVmin(0.0), aVmax(0.0), dUmax(0.0), dVmax(0.0);

	for (faceExplorer.Init(aShape, TopAbs_FACE); faceExplorer.More(); faceExplorer.Next())
	{

		TopLoc_Location loc;
		TopoDS_Face aFace = TopoDS::Face(faceExplorer.Current());

		BRepTools::UVBounds(aFace, aUmin, aUmax, aVmin, aVmax);
		dUmax = (aUmax - aUmin);
		dVmax = (aVmax - aVmin);

		Handle_Poly_Triangulation triFace = BRep_Tool::Triangulation(aFace, loc);
		Standard_Integer nTriangles = triFace->NbTriangles();

		gp_Pnt vertex1;
		gp_Pnt vertex2;
		gp_Pnt vertex3;

		Standard_Integer nVertexIndex1 = 0;
		Standard_Integer nVertexIndex2 = 0;
		Standard_Integer nVertexIndex3 = 0;

		TColgp_Array1OfPnt nodes(1, triFace->NbNodes());
		Poly_Array1OfTriangle triangles(1, triFace->NbTriangles());
		nodes = triFace->Nodes();

		triFace->UVNodes();

		triangles = triFace->Triangles();
		const TColgp_Array1OfPnt2d& aUVNodes = triFace->UVNodes();

		//计算法向量
		Poly_Connect aPolyConnect(triFace);
		// Extracts vertices & normals from nodes
		TColgp_Array1OfDir aNormals(nodes.Lower(), nodes.Upper());
		ComputeNormal(aFace, aPolyConnect, aNormals);

		for (Standard_Integer i = 1; i <= nTriangles; i++)
		{

			Poly_Triangle aTriangle = triangles.Value(i);
			aTriangle.Get(nVertexIndex1, nVertexIndex2, nVertexIndex3);

			vertex1 = nodes.Value(nVertexIndex1);
			vertex2 = nodes.Value(nVertexIndex2);
			vertex3 = nodes.Value(nVertexIndex3);

			gp_XYZ vector12(vertex2.XYZ() - vertex1.XYZ());
			gp_XYZ vector13(vertex3.XYZ() - vertex1.XYZ());
			gp_XYZ normal = vector12.Crossed(vector13);

			Standard_Real rModulus = normal.Modulus();

			if (rModulus > gp::Resolution())
			{
				normal.Normalize();
			}
			else
			{
				normal.SetCoord(0., 0., 0.);
			}

			vertices->push_back(osg::Vec3(vertex1.X(), vertex1.Y(), vertex1.Z()));
			vertices->push_back(osg::Vec3(vertex2.X(), vertex2.Y(), vertex2.Z()));
			vertices->push_back(osg::Vec3(vertex3.X(), vertex3.Y(), vertex3.Z()));

			//法向量
			gp_Dir normal1 = aNormals.Value(nVertexIndex1);
			gp_Dir normal2 = aNormals.Value(nVertexIndex2);
			gp_Dir normal3 = aNormals.Value(nVertexIndex3);

			normals->push_back(osg::Vec3(normal.X(), normal.Y(), normal.Z()));
			normals->push_back(osg::Vec3(normal.X(), normal.Y(), normal.Z()));
			normals->push_back(osg::Vec3(normal.X(), normal.Y(), normal.Z()));

			//算纹理
			const gp_Pnt2d aTexel = gp_Pnt2d((-0 + (1 * (aUVNodes(nVertexIndex1).X() - aUmin)) / dUmax) / 1,
				(-0 + (1 * (aUVNodes(nVertexIndex1).Y() - aVmin)) / dVmax) / 1);

			const gp_Pnt2d aTexe2 = gp_Pnt2d((-0 + (1 * (aUVNodes(nVertexIndex2).X() - aUmin)) / dUmax) / 1,
				(-0 + (1 * (aUVNodes(nVertexIndex2).Y() - aVmin)) / dVmax) / 1);

			const gp_Pnt2d aTexe3 = gp_Pnt2d((-0 + (1 * (aUVNodes(nVertexIndex3).X() - aUmin)) / dUmax) / 1,
				(-0 + (1 * (aUVNodes(nVertexIndex3).Y() - aVmin)) / dVmax) / 1);


			texs->push_back(osg::Vec2(aTexel.X(), aTexel.Y()));
			texs->push_back(osg::Vec2(aTexe2.X(), aTexe2.Y()));
			texs->push_back(osg::Vec2(aTexe3.X(), aTexe3.Y()));

		}
	}

	//
	osg::ref_ptr<osg::Texture2D> spTexture2D = new osg::Texture2D;
	osg::ref_ptr<osg::Image> spImage = osgDB::readImageFile("D://jiaju.bmp");
	if (spImage.valid())
	{
		spTexture2D->setImage(spImage.get());
	}

	spTexture2D->setWrap(osg::Texture2D::WRAP_S, osg::Texture::CLAMP);
	spTexture2D->setWrap(osg::Texture2D::WRAP_T, osg::Texture::CLAMP);
	spTexture2D->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture::LINEAR);
	spTexture2D->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture::LINEAR);
	//


	triGeom->setVertexArray(vertices.get());
	triGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, vertices->size()));
	triGeom->setNormalArray(normals);
	triGeom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);

	triGeom->setTexCoordArray(0, texs, osg::Array::Binding::BIND_PER_PRIMITIVE_SET);
	triGeom->getOrCreateStateSet()->setTextureAttributeAndModes(0, spTexture2D.get(), osg::StateAttribute::ON);

	triGeom->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON);


	geode->addDrawable(triGeom);
	return geode;
}

//底面中心，半径，高度，底面中心和顶面中心的连线所在的向量
osg::ref_ptr<osg::MatrixTransform> OsgExToolSet::createCylinderGeode(osg::Vec3 pos, double radius, double height, osg::Vec3f n, osg::Vec4 color)
{
	osg::Geode *geode = new osg::Geode();

	//精细度
	osg::Quat quat;
	quat.makeRotate(osg::Vec3(0, 0, 1), n);
	osg::ref_ptr<osg::TessellationHints> hints1 = new osg::TessellationHints();
	//设置精细度
	hints1->setDetailRatio(0.8f);

	//底面中心，方向，高度
	osg::Vec3f justPos = osg::Vec3f(0, 0, height * 0.5);
	osg::ref_ptr<osg::Cylinder> cylinder = new osg::Cylinder(justPos, radius, height);

	osg::ShapeDrawable *draw1 = new osg::ShapeDrawable(cylinder, hints1);
	draw1->setColor(color);

	draw1->setDataVariance(osg::Object::DYNAMIC);
	draw1->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON);
	draw1->setUseVertexBufferObjects(true);
	draw1->setUseDisplayList(false);

	geode->addDrawable(draw1);

	osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;
	//显示包围
	{
		osg::Geode* boxGeod = new osg::Geode();
		boxGeod->setName("HoleBox");

		osg::ref_ptr<osg::Cylinder> tempCylinder = new osg::Cylinder(justPos, radius + 2, height + 2);

		osg::ref_ptr<osg::ShapeDrawable> tempDraw = new osg::ShapeDrawable(tempCylinder, hints1);

		osg::BoundingBox box = tempDraw->getBoundingBox();

		OsgExToolSet::createBoxTriangles(boxGeod, box);

		//mt->addChild(boxGeod);
	}


	mt->addChild(geode);

	geode->setName("holeGode");

	osg::Matrixd mat;
	mat.makeRotate(quat);
	mat.setTrans(pos);
	mt->setMatrix(mat);

	return mt;
}

osg::ref_ptr<osg::Geode> OsgExToolSet::createShpereGeode(osg::Vec3 center, double radius)
{
	osg::Geode *geode = new osg::Geode();

	//精细度
	osg::TessellationHints* hints1 = new osg::TessellationHints();
	//设置精细度
	hints1->setDetailRatio(0.8f);

	//创建圆柱体
	osg::Sphere *shpere = new osg::Sphere(center, radius);

	osg::ShapeDrawable *draw1 = new osg::ShapeDrawable(shpere, hints1);

	draw1->setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0));

	geode->addDrawable(draw1);

	return geode;
}

osg::ref_ptr<osg::Geode> OsgExToolSet::make_cube(float _dx, float _dy, float _dz)
{
	//static std::map<int, int> xxx;
	//xxx[1] = 2;
	//xxx[2] = 3;

	//mss[3] = 7;


	TopoDS_Shape t_topo_box = BRepPrimAPI_MakeBox(_dx, _dy, _dz).Shape();

	TopoDS_Shape t_topo_box2 = BRepPrimAPI_MakeBox(gp_Pnt(5, 5, -10), 4, 4, 30).Shape();

	TopoDS_Shape shape_fuse = BRepAlgoAPI_Cut(t_topo_box, t_topo_box2);

	//BRepMesh_IncrementalMesh iMesh(t_topo_box, 1);

	//std::vector<osg::Vec3f> points;
	////取出所有的顶点
	//for (TopExp_Explorer anExpSF(t_topo_box, TopAbs_FACE); anExpSF.More(); anExpSF.Next())
	//{
	//	TopLoc_Location aLoc;
	//	Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(anExpSF.Current()), aLoc);

	//	if (aTriangulation.IsNull())
	//		continue;

	//	const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
	//	const Poly_Array1OfTriangle& triangles = aTriangulation->Triangles();
	//	Standard_Integer nTriangles = aTriangulation->NbTriangles();
	//	//绘制点
	//	for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
	//	{
	//		gp_Pnt aPnt = aNodes(aNodeIter);
	//		points.push_back(osg::Vec3f(aPnt.X(), aPnt.Y(), aPnt.Z()));
	//	}

	//	gp_Pnt vertex1;
	//	gp_Pnt vertex2;
	//	gp_Pnt vertex3;

	//	Standard_Integer nVertexIndex1 = 0;
	//	Standard_Integer nVertexIndex2 = 0;
	//	Standard_Integer nVertexIndex3 = 0;


	//	for (Standard_Integer i = 1; i <= nTriangles; i++)
	//	{

	//		Poly_Triangle aTriangle = triangles.Value(i);
	//		aTriangle.Get(nVertexIndex1, nVertexIndex2, nVertexIndex3);

	//		vertex1 = aNodes.Value(nVertexIndex1);
	//		vertex2 = aNodes.Value(nVertexIndex2);
	//		vertex3 = aNodes.Value(nVertexIndex3);
	//	}
	//}

	//return fillTriangles(shape_fuse,
	//true,
	//gp_Pnt2d(0, 0),
	//gp_Pnt2d(1, 1),
	//gp_Pnt2d(1, 1));
	return BuildShapeMesh(shape_fuse);
	//return createBoxsGeode(points, 10, 10, osg::Vec4(0.5, 0.0, 0.0, 1.0));
}

osg::ref_ptr<osg::Geode> OsgExToolSet::createGrid(double length, double div)
{
	double len = length * 0.5;
	int num = (int)(length / div);

	osg::Geode *geode = new osg::Geode();
	osg::Geometry *geom = new osg::Geometry();

	osg::Vec3Array *vertices = new osg::Vec3Array();
	int i;
	//int num = 40;

	osg::Vec3f hf(-len, -len, 0);
	osg::Vec3f hs(len, -len, 0);

	osg::Vec3f vf(-len, -len, 0);
	osg::Vec3f vs(-len, len, 0);

	for (i = 0; i <= num; i++)
	{
		osg::Vec3f hfv = osg::Vec3f(0, 1, 0) * i * div + hf;
		osg::Vec3f hsv = osg::Vec3f(0, 1, 0) * i * div + hs;

		vertices->push_back(hfv);
		vertices->push_back(hsv);

		osg::Vec3f vfv = osg::Vec3f(1, 0, 0) * i * div + vf;
		osg::Vec3f vsv = osg::Vec3f(1, 0, 0) * i * div + vs;

		vertices->push_back(vfv);
		vertices->push_back(vsv);

	}

	geom->setVertexArray(vertices);

	osg::Vec4Array* colors = new osg::Vec4Array();
	colors->push_back(osg::Vec4(0.3f, 0.3f, 0.3f, 1.0f));


	geom->setColorArray(colors);
	geom->setColorBinding(osg::Geometry::BIND_OVERALL);

	geom->setName("ChaiDanGrid");

	geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, vertices->size()));
	geode->addDrawable(geom);

	return geode;
}
